package org.smartboot.socket.benchmark;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smartboot.socket.MessageProcessor;
import org.smartboot.socket.StateMachineEnum;
import org.smartboot.socket.buffer.BufferPagePool;
import org.smartboot.socket.transport.AioQuickClient;
import org.smartboot.socket.transport.AioSession;
import org.smartboot.socket.transport.WriteBuffer;
import util.ByteExtUtil;
import util.FormatTransfer;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadFactory;

/**
 * @author 三刀
 * @version V1.0 , 2018/11/23
 */
public class StringClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(StringClient.class);

    public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
//        System.setProperty("smart-socket.client.pageSize", (1024 * 1024 * 64) + "");
        System.setProperty("smart-socket.session.writeChunkSize", "" + (1024 * 1024));

        BufferPagePool bufferPagePool = new BufferPagePool(1024 * 1024 * 32, 10, true);
        AsynchronousChannelGroup asynchronousChannelGroup = AsynchronousChannelGroup.withFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "ClientGroup");
            }
        });
        for (int i = 0; i < 1; i++) {
            new Thread() {
                @Override
                public void run() {
                    try {
                        new StringClient().test1(asynchronousChannelGroup, bufferPagePool);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }.start();
        }

    }

    private void test1(AsynchronousChannelGroup asynchronousChannelGroup, BufferPagePool bufferPagePool) throws InterruptedException, ExecutionException, IOException {
        AioQuickClient<String> client = new AioQuickClient<>("192.168.1.4", 8088, new StringProtocol(), new MessageProcessor<String>() {
            @Override
            public void process(AioSession<String> session, String msg) {
//                LOGGER.info(msg);
            }

            @Override
            public void stateEvent(AioSession<String> session, StateMachineEnum stateMachineEnum, Throwable throwable) {
                if (throwable != null) {
                    throwable.printStackTrace();
                }
            }
        });
        client.setBufferPagePool(bufferPagePool);
//        client.setWriteQueueCapacity(10);
        AioSession<String> session = client.start(asynchronousChannelGroup);
        WriteBuffer outputStream = session.writeBuffer();

//        byte[] data = "smart-socket".getBytes();
        int index = 0;
        byte[] data = new byte[25];
        //固定 0xAA 0xF5 长度2
//        byte[] a1 = new byte[]{0xAA, 0xF5, 0xF, 0x5};
        data[0] = (byte) 0xAA;
        data[1] = (byte) 0xF5;
//        System.arraycopy(a1, 0, data, index, a1.length);
        index += 2;
        //长度 长度2
        int length = 15;
        byte[] bytes = FormatTransfer.toLH((short) length);
        System.arraycopy(bytes, 0, data, index, bytes.length);
//        index += bytes.length;
//        //版本域
//        data[++index] = (byte) 0x10;
//        int seq = 0;
//        byte[] bytes1 = ByteExtUtil.getBytes(seq);
//        System.arraycopy(bytes1, 0, data, index, bytes.length);
//        int num = (int) (Math.random() * 10) + 1;
//        for (int i = 0; i < 100; i++) {
//            int num = i + 1;
//            outputStream.writeInt(data.length * num);
//            while (num-- > 0) {
//                outputStream.write(data);
//            }
//        }
//        outputStream.writeInt(data.length);
//        outputStream.write(data);
        while (true) {
            int num = (int) (Math.random() * 10) + 1;
            outputStream.writeInt(data.length * num);
            while (num-- >0){
                outputStream.write(data);
            }
//            Thread.sleep(100);
        }


//            Thread.sleep(100);
    }

    public void test(AsynchronousChannelGroup asynchronousChannelGroup, BufferPagePool bufferPagePool) throws InterruptedException, ExecutionException, IOException {
        AioQuickClient<String> client = new AioQuickClient<>("192.168.1.4", 8088, new StringProtocol(), new MessageProcessor<String>() {
            @Override
            public void process(AioSession<String> session, String msg) {
//                LOGGER.info(msg);
            }

            @Override
            public void stateEvent(AioSession<String> session, StateMachineEnum stateMachineEnum, Throwable throwable) {
                if (throwable != null) {
                    throwable.printStackTrace();
                }
            }
        });
        client.setBufferPagePool(bufferPagePool);
        client.setWriteQueueCapacity(10);
        AioSession<String> session = client.start(asynchronousChannelGroup);
        WriteBuffer outputStream = session.writeBuffer();

//        byte[] data = "smart-socket".getBytes();
        int index = 0;
        byte[] data = new byte[25];
        //固定 0xAA 0xF5 长度2
//        byte[] a1 = new byte[]{0xAA, 0xF5, 0xF, 0x5};
        data[0] = (byte) 0xAA;
        data[1] = (byte) 0xF5;
//        System.arraycopy(a1, 0, data, index, a1.length);
        index += 2;
        //长度 长度2
        int length = 15;
        byte[] bytes = FormatTransfer.toLH((short) length);
        System.arraycopy(bytes, 0, data, index, bytes.length);

        while (true) {
            int num = (int) (Math.random() * 10) + 1;
            outputStream.writeInt(data.length * num);
            while (num-- > 0) {
                outputStream.write(data);
            }

//            Thread.sleep(100);
        }
    }
}
